package com.ctsi.commons.util.defImpl;

import com.ctsi.commons.util.cache.IutilCache;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 简单实现
 * 
 * @author yueming
 * 
 * @param <K>
 * @param <V>
 */
public class ReadWriteCache<K, V> implements IutilCache<K, V> {
	private final ReadWriteLock lock = new ReentrantReadWriteLock();
	private final Lock readLock = lock.readLock(); // 读锁
	private final Lock writeLock = lock.writeLock(); // 写锁
	private final Map<K, V> cache = new HashMap<K, V>();

	private final String name;

	public ReadWriteCache(String name) {
		this.name = name;
	}
	@Override
	public void clear() {

		writeLock.lock();
		try {
			cache.clear();
		} finally {
			writeLock.unlock();
		}

	}
	@Override
	public void clusterNotify(Serializable id) {

	}
	@Override
	public boolean containsKey(Object key) {
		// 获得读锁:
		readLock.lock();
		try {

			return cache.containsKey(key);
		} finally {
			// 确保读锁在方法返回前被释放:
			readLock.unlock();
		}
	}
	@Override
	public int getMaxSize() {

		return 0;
	}
	@Override
	public String getName() {

		return name;
	}
	@Override
	public boolean isCluster() {

		return false;
	}


	@Override
	public void removeByPrefix(String prefix) {

		writeLock.lock();

		try {
			Iterator<K> it = cache.keySet().iterator();
			while (it.hasNext()) {
				K key = it.next();
				if (key instanceof String) {
					if (((String) key).startsWith(prefix)) {
						cache.remove(key);
					}
				}
			}

		} finally {

			writeLock.unlock();
		}

	}
	@Override
	public void setCluster(boolean cluster) {

	}
	@Override
	public void setMaxSize(int maxSize) {

	}
	@Override
	public void setUseSoftReference(boolean useSoftReference) {

	}
	@Override
	public int size() {
		// 获得读锁:
		readLock.lock();
		try {

			return cache.size();
		} finally {
			// 确保读锁在方法返回前被释放:
			readLock.unlock();
		}
	}


	@Override
	public List<V> values() {

		// 获得读锁:
		readLock.lock();
		try {

			return new ArrayList<V>(cache.values());

		} finally {
			// 确保读锁在方法返回前被释放:
			readLock.unlock();
		}
	}
	@Override
	public V get(Object key) {
		// 获得读锁:
		readLock.lock();
		try {

			return cache.get(key);
		} finally {
			// 确保读锁在方法返回前被释放:
			readLock.unlock();
		}
	}
	@Override
	public V put(K key, V value) {
		writeLock.lock();

		try {
			return cache.put(key, value);
		} finally {

			writeLock.unlock();
		}
	}
	@Override
	public V remove(K key) {
		writeLock.lock();

		try {
			return cache.remove(key);
		} finally {

			writeLock.unlock();
		}
	}
	@Override
	public Set<? extends K> getCacheLineKeys() {
 
		readLock.lock();
		try {

			return Collections.unmodifiableSet(cache.keySet());
		} finally {
			readLock.unlock();
		}
		
	
	}
}
